namespace Angelus.Oracle.Entity.OracleClient
{
    using System;
    using System.Data;
    using System.Data.Common;
    using System.Data.Metadata.Edm;
    using global::Oracle.DataAccess.Client;

    /// <summary>
    /// Description of OracleCommand.
    /// </summary>
    public class DbOracleCommand : DbCommand, ICloneable
    {
        #region Fields

        private DbOracleConnection _connection;
        private bool _designTimevisible = true;
        private PrimitiveType[] _expectedColumnTypes;
        private DbCommand _command = new OracleCommand();
        private DbTransaction _transaction;

        #endregion

        #region Constructors

        /// <summary>
        /// 
        /// </summary>
        public DbOracleCommand()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="commandText"></param>
        public DbOracleCommand(string commandText)
        {
            this.BuildUp(commandText, null, null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="connection"></param>
        public DbOracleCommand(string commandText, DbConnection connection)
        {
            this.BuildUp(commandText, connection, null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="connection"></param>
        /// <param name="transaction"></param>
        public DbOracleCommand(string commandText, DbConnection connection, DbTransaction transaction)
        {
            this.BuildUp(commandText, connection, transaction);
        }

        #endregion

        #region Properties

        /// <summary>
        /// 
        /// </summary>
        internal PrimitiveType[] ExpectedColumnTypes
        {
            get { return this._expectedColumnTypes; }
            set { this._expectedColumnTypes = value; }
        }

        #endregion

        #region DbCommand Overrides

        /// <summary>
        /// 
        /// </summary>
        public override string CommandText
        {
            get { return this._command.CommandText; }
            set { this._command.CommandText = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public override int CommandTimeout
        {
            get { return this._command.CommandTimeout; }
            set { this._command.CommandTimeout = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public override CommandType CommandType
        {
            get { return this._command.CommandType; }
            set { this._command.CommandType = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        protected override DbConnection DbConnection
        {
            get { return this._connection; }
            set
            {
                this._connection = (DbOracleConnection) value;
                this._command.Connection = this._connection.InnerConnection;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        protected override DbParameterCollection DbParameterCollection
        {
            get { return this._command.Parameters; }
        }

        /// <summary>
        /// 
        /// </summary>
        protected override DbTransaction DbTransaction
        {
            get { return this._transaction; }
            set
            {
                this._transaction = value;
                this._command.Transaction = this._transaction;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public override bool DesignTimeVisible
        {
            get { return this._designTimevisible; }
            set { this._designTimevisible = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public override UpdateRowSource UpdatedRowSource
        {
            get { return this._command.UpdatedRowSource; }
            set { this._command.UpdatedRowSource = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public override void Cancel()
        {
            this._command.Cancel();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected override DbParameter CreateDbParameter()
        {
            return this._command.CreateParameter();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="behavior"></param>
        /// <returns></returns>
        protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
        {
            return new DbOracleDataReader(this._command.ExecuteReader(behavior), this._expectedColumnTypes);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int ExecuteNonQuery()
        {
            return this._command.ExecuteNonQuery();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override object ExecuteScalar()
        {
            return this._command.ExecuteScalar();
        }

        /// <summary>
        /// 
        /// </summary>
        public override void Prepare()
        {
            this._command.Prepare();
        }

        #endregion

        #region ICloneable Implementation

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        object ICloneable.Clone()
        {
            return new DbOracleCommand
                       {
                           _connection = this._connection,
                           _expectedColumnTypes = this._expectedColumnTypes,
                           _command = ((DbCommand) ((ICloneable) this._command).Clone())
                       };
        }

        #endregion

        #region Private Implementation

        /// <summary>
        /// 
        /// </summary>
        /// <param name="commandText"></param>
        /// <param name="connection"></param>
        /// <param name="transaction"></param>
        private void BuildUp(string commandText, DbConnection connection, DbTransaction transaction)
        {
            this.CommandText = commandText;
            Connection = connection;
            Transaction = transaction;
        }

        #endregion
    }
}